<?php

namespace app\controller\admin\module\admin\components;


use app\components\traits\Singleton;
use think\exception\ValidateException;

class Account
{
    use Singleton;
    protected string $modelName = 'admin';

    /**
     * 更新账号信息
     * @return array
     */
    public function account(): array
    {
        $info = $this->model->getInfo(['id' => $this->baseInfo['id']], 'id, salt, pwd');
        $avatar = values('avatar');
        $nick = values('nick');
        try {
            validate([
                'nick|昵称' => ['require'],
            ])->check([
                'nick' => $nick,
            ]);
            $data = [
                'nick' => $nick
            ];
            !empty($avatar) and $data['avatar'] = $avatar;
            if(!$this->model->edit(['id' => $info['id']], $data)){
                throw new ValidateException('保存失败');
            }
            putAdminLog('管理员 ' . $this->baseInfo['name'] .  '更新自身账号信息|nick: ' . $nick . '|avatar: ' . $avatar);
            return responseArrayMsg('保存成功', 200);
        }catch (ValidateException $e){
            return responseArrayMsg($e->getError());
        }
    }

    /**
     * 修改密码
     * @return array
     */
    public function password(): array
    {
        $oldpassword = values('oldpwd');   //密码
        $password = values('newpwd');   //密码
        $repassword = values('confirmpwd');   //密码
        try {
            validate([
                'oldpassword|旧密码' => ['require'],
                'password|新密码' => ['require', 'different:oldpassword'],
                'repassword|二次输入密码' => ['require', 'confirm:password'],
            ], [
                'oldpassword.require' => '请输入旧密码',
                'password.require' => '请输入新密码',
                'password.different' => '新密码不能与旧密码相同',
                'repassword.require' => '请再次输入新密码',
                'repassword.confirm' => '两次输入密码不一致',
            ])->check([
                'oldpassword' => $oldpassword,
                'password' => $password,
                'repassword' => $repassword,
            ]);
            $info = $this->model->getInfo(['id' => $this->baseInfo['id']], 'id, salt, pwd');
            if(!password_verify(sha1($info['salt'] . $oldpassword), $info['pwd'])){
                throw new ValidateException('原密码不正确');
            }
            $salt = randomSalt(6);
            if($this->model->edit(['id' => $info['id']], [
                'salt' => $salt,
                'pwd' => password_hash(sha1($salt . $password), PASSWORD_BCRYPT, ['cost' => 12,])
            ])){
                deleteToken($this->baseInfo['token']);
                putAdminLog('管理员' . $this->baseInfo['name'] . '修改密码');
                return responseArrayMsg('修改成功，请重新登录', 1001);
            }
            return responseArrayMsg('修改失败');
        }catch (ValidateException $e){
            return responseArrayMsg($e->getError());
        }

    }


    /**
     * 邮箱验证码长度
     * @var int
     */
    private int $emailCodeLength = 6;
    /**
     * 发送邮箱验证码
     * @return array
     */
    public function sendEmail(): array
    {
        $email = values('email');
        try {
            validate([
                'email|邮箱' => ['require', 'email'],
            ])->check([
                'email' => $email,
            ]);
            if(!empty($this->baseInfo['email']) and $email == $this->baseInfo['email']){
                throw new ValidateException('不能与原邮箱一致');
            }
            if($this->model->getInfo([['email', '=', $email], ['id', '<>', $this->baseInfo['id']]], 'id')){
                throw new ValidateException('邮箱已被占用，请更换一个邮箱');
            }
//            if(getCaches('email_code_' . $this->baseInfo['token'])){
//                return responseArrayMsg('验证码还在有效期', 204);
//            }
            $useOldCode = getCacheTTL('email_code_' . $this->baseInfo['token']) > 60; //如果没有旧的/旧的验证码还有60s过期，则重新生成验证码
            $code = $useOldCode ? getCaches('email_code_' . $this->baseInfo['token'], 0) : randomCode($this->emailCodeLength);
            $res = factory('email.email')->isHTML()->send($email, view('/template/email/mail1', ['code' => $code])->getContent(), '绑定邮箱');
            if($res['code'] != 200){
                throw new ValidateException($res['msg']);
            }
            setCaches('email_code_countdown_' . $this->baseInfo['token'], time(), 60); //设置倒计时
            $useOldCode or setCaches('email_code_' . $this->baseInfo['token'], $code, REDIS_MAIL_TIME_OUT); //如果旧验证码为空，则设置新的验证码
            putAdminLog('管理员' . $this->baseInfo['name'] . '发送了邮箱验证码');
            return responseArrayMsg($res['msg'], $res['code']);
        }catch (ValidateException $e){
            return responseArrayMsg($e->getError());
        }
    }
    /**
     * 绑定邮箱验证码
     * @return array
     */
    public function email(): array
    {
        $email = values('email');
        $code = values('code', 0);
        try {
            validate([
                'email|邮箱' => ['require', 'email'],
                'code|验证码' => ['require', 'number', 'length:' . $this->emailCodeLength],
            ])->check([
                'email' => $email,
                'code' => $code,
            ]);
        }catch (ValidateException $e){
            return responseArrayMsg($e->getError());
        }
        $key = 'email_code_' . $this->baseInfo['token'];
        $sendCode = getCaches($key, 0);
        if(empty($sendCode)){
            return responseArrayMsg('验证码已经失效');
        }
        if(validate(['code|验证码' => 'require|number|length:'. $this->emailCodeLength ])->check(['code' => $code]) and $code === $sendCode){
            delCaches($key);
            delCaches('email_code_countdown_' . $this->baseInfo['token']);
            $this->model->edit(['id' => $this->baseInfo['id']], ['email' => $email]);
            putAdminLog('管理员' . $this->baseInfo['id'] . '绑定邮箱' . $email);
            return responseArrayMsg('绑定成功', 200);
        }
        return responseArrayMsg('验证码错误');
    }

}